package com.tancire.arts.service.impl;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import cn.hutool.core.util.ObjectUtil;
import com.tancire.arts.domain.MoveArt;
import com.tancire.common.exception.NoteException;
import com.tancire.common.utils.DateUtils;
import com.tancire.common.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import com.tancire.arts.mapper.NoteArticleMapper;
import com.tancire.arts.domain.NoteArticle;
import com.tancire.arts.service.INoteArticleService;

/**
 * 文章管理Service业务层处理
 *
 * @author 陈超
 * @date 2024-09-23
 */
@Service
public class NoteArticleServiceImpl implements INoteArticleService {

    @Resource
    private NoteArticleMapper noteArticleMapper;

    /**
     * 查询文章管理
     *
     * @param id 文章管理主键
     * @return 文章管理
     */
    @Override
    public NoteArticle selectNoteArticleById(Long id) {
        return noteArticleMapper.selectNoteArticleById(id);
    }

    /**
     * 查询文章管理列表
     *
     * @param noteArticle 文章管理
     * @return 文章管理
     */
    @Override
    public List<NoteArticle> selectNoteArticleList(NoteArticle noteArticle) {
        return noteArticleMapper.selectNoteArticleList(noteArticle);
    }

    /**
     * 新增文章管理
     *
     * @param noteArticle 文章管理
     * @return 结果
     */
    @Override
    public int insertNoteArticle(NoteArticle noteArticle) {
        noteArticle.setCreateTime(DateUtils.getNowDate());
        noteArticle.setCreateBy(SecurityUtils.getUserId().toString());
        // 初始化排序
        NoteArticle lastArt = noteArticleMapper.selectLastChild(noteArticle.getPid());
        if (null != lastArt && null != lastArt.getArtSort()) {
            noteArticle.setArtSort(lastArt.getArtSort() + 1);
        } else {
            noteArticle.setArtSort(1);
        }
        return noteArticleMapper.insertNoteArticle(noteArticle);
    }

    /**
     * 修改文章管理
     *
     * @param noteArticle 文章管理
     * @return 结果
     */
    @Override
    public int updateNoteArticle(NoteArticle noteArticle) {
        noteArticle.setUpdateTime(DateUtils.getNowDate());
        return noteArticleMapper.updateNoteArticle(noteArticle);
    }

    /**
     * 批量删除文章管理
     *
     * @param ids 需要删除的文章管理主键
     * @return 结果
     */
    @Override
    public int deleteNoteArticleByIds(Long[] ids) {
        return noteArticleMapper.deleteNoteArticleByIds(ids);
    }

    /**
     * 删除文章管理信息
     *
     * @param id 文章管理主键
     * @return 结果
     */
    @Override
    public int deleteNoteArticleById(Long id) {
        return noteArticleMapper.deleteNoteArticleById(id);
    }

    /**
     * 查询文章树
     *
     * @param noteArticle
     * @return
     */
    @Override
    public List<NoteArticle> selectNoteArticleTree(NoteArticle noteArticle) {
        Long noteId = noteArticle.getNoteId();
        if (null == noteId) {
            throw new NoteException("所属作品集不能为空");
        }
        List<NoteArticle> allArt = this.noteArticleMapper.selectNoteArticleListSimple(noteArticle);
        // 先筛选出一级节点，然后递归子节点
        if (ObjectUtil.isNotEmpty(allArt)) {
            List<NoteArticle> firstArt = allArt.stream().filter(x -> 0L == x.getPid()).collect(Collectors.toList());
            // 循环处理子节点
            for (NoteArticle parentArt : firstArt) {
                this.handleChild(parentArt, allArt);
            }
            return firstArt;
        }
        return Collections.emptyList();
    }

    /**
     * 移动目录
     *
     * @param moveArt
     */
    @Override
    public void moveNoteArticle(MoveArt moveArt) {
        Long sourceId = moveArt.getSourceId();
        Long targetId = moveArt.getTargetId();
        String sort = moveArt.getSort();

        NoteArticle updateData = new NoteArticle();
        // 获取原始节点
        if ("inner".equals(sort)) {
            // 目标父节点没有子节点
            updateData.setPid(targetId);
            updateData.setArtSort(1);
            updateData.setId(sourceId);
            this.noteArticleMapper.updateNoteArticle(updateData);
        } else {
            // 目标节点至少有一个兄弟
            // 获取目标节点
            NoteArticle targetNoteArticle = this.noteArticleMapper.selectNoteArticleById(targetId);
            // 获取目标节点兄弟节点
            List<NoteArticle> brotherList = this.selectBrotherList(targetNoteArticle, sourceId);
            // 循环更新节点排序
            int sortNum = 1;
            for (NoteArticle noteArt : brotherList) {
                Long id = noteArt.getId();
                // 构建更新实体
                NoteArticle updateBrother = new NoteArticle();
                updateBrother.setId(id);
                if (Objects.equals(id, targetNoteArticle.getId())) {
                    // 匹配到目标节点
                    if ("after".equals(sort)) {
                        // 后面
                        updateBrother.setArtSort(sortNum);
                        sortNum++;
                        // 将当前节点放在目标节点后
                        updateData.setPid(targetNoteArticle.getPid());
                        updateData.setArtSort(sortNum);
                        updateData.setId(sourceId);
                        this.noteArticleMapper.updateNoteArticle(updateData);
                    } else {
                        // 将当前节点放在目标节点前面
                        updateData.setPid(targetNoteArticle.getPid());
                        updateData.setArtSort(sortNum);
                        updateData.setId(sourceId);
                        this.noteArticleMapper.updateNoteArticle(updateData);
                        // 排序增加
                        sortNum++;
                        updateBrother.setArtSort(sortNum);
                    }
                } else {
                    updateBrother.setArtSort(sortNum);
                }
                this.noteArticleMapper.updateNoteArticle(updateBrother);
                sortNum++;
            }
        }
    }

    private List<NoteArticle> selectBrotherList(NoteArticle article, Long extId) {
        NoteArticle query = new NoteArticle();
        query.setPid(article.getPid());
        query.setNoteId(article.getNoteId());
        List<NoteArticle> noteArticles = this.noteArticleMapper.selectNoteArticleListSimple(query);
        return noteArticles.stream().filter(x -> !Objects.equals(x.getId(), extId)).collect(Collectors.toList());
    }

    /**
     * 递归处理子节点
     *
     * @param parentArt
     * @param allArt
     */
    private void handleChild(NoteArticle parentArt, List<NoteArticle> allArt) {
        Long id = parentArt.getId();
        List<NoteArticle> children = allArt.stream().filter(x -> Objects.equals(x.getPid(), id)).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(children)) {
            for (NoteArticle child : children) {
                handleChild(child, allArt);
            }
        }
        parentArt.setChildren(children);
    }
}
